package com.scmt.hmzd.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.db.sql.Order;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scmt.core.common.utils.ResultUtil;
import com.scmt.core.common.utils.SecurityUtil;
import com.scmt.core.common.vo.Result;
import com.scmt.hmzd.config.WeixinPayConfig;
import com.scmt.hmzd.config.WxConfig;
import com.scmt.hmzd.entity.HmOrder;
import com.scmt.hmzd.entity.HmProject;
import com.scmt.hmzd.entity.HmWxUser;
import com.scmt.hmzd.enums.OrderEnum;
import com.scmt.hmzd.service.IHmOrderService;
import com.scmt.hmzd.service.IHmProjectService;
import com.scmt.hmzd.utils.AmountUtil;
import com.scmt.hmzd.utils.HttpClientUtil;
import com.scmt.hmzd.utils.WxUtils;
import com.scmt.hmzd.utils.XmlUtil;
import com.scmt.hmzd.wxLoginUtils.WxSecurityUtil;
import io.swagger.annotations.Api;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.jdom2.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(tags = "微信支付接口")
@RestController
@RequestMapping("/scmt/appMain")
@Slf4j
public class WxPayController {
    @Autowired
    private IHmOrderService iHmOrderService;
    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private WxSecurityUtil securityUtil;
    @Autowired
    private IHmProjectService iHmProjectService;


    @GetMapping("/sendPay")
    public Result<Object> sendPay(@RequestParam String orderId, HttpServletRequest request) throws IOException {
        try {
            HmWxUser currentWxUser = securityUtil.getCurrentWxUser();
            if(currentWxUser == null) {
                return ResultUtil.error("用户不明确！无法支付");
            }

            WxUtils wxUtils = new WxUtils();
            HmOrder hmOrder = iHmOrderService.getById(orderId);
            if (hmOrder == null) {
                return ResultUtil.error("订单异常，拉起支付失败！");
            }

            if (hmOrder.getStatus() == OrderEnum.ORDER_CANCEL.getIndex()) {
                return ResultUtil.error("订单已失效，请重新下单");
            }

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("appid", WeixinPayConfig.appid);//微信支付分配的公众账号ID(企业corpid即为此appId)
            data.put("mch_id", WeixinPayConfig.mch_id);
            data.put("nonce_str", wxUtils.getRandomString(32)); // 通过微信工具类生成 随机字符串"会员充值”);
            data.put("body", "项目服务费用");  // 商品描述xx
            data.put("out_trade_no", hmOrder.getId()); //订单号 唯一
            data.put("total_fee", Long.parseLong(AmountUtil.convertDollar2Cent(hmOrder.getOrderPrice().toString()))); // 标价金额
//            data.put("total_fee", 1); // 标价金额  测试金额1分
            data.put("spbill_create_ip", wxUtils.getIpAddr(request));  // 终端IP
            data.put("openid", currentWxUser.getOpenid());  // 公众号用户的openid
            data.put("notify_url", "https://jcepay.lzjczl.com/hmzdApi/scmt/appMain/payResult");//支付回调通知地址
            data.put("trade_type", "JSAPI"); //交易类型
            data.put("sign", WxConfig.getSign(data));
            String xml = XmlUtil.genXml(data);
            HttpResponse httpResponse = HttpClientUtil.sendXMLDataByPost(WeixinPayConfig.url, xml);
            HttpEntity entity = httpResponse.getEntity();
            InputStream content = entity.getContent();
            Map<String, Object> elementValueToMap = wxUtils.getElementValueToMap(content);
            log.info("支付预下单： {}", elementValueToMap);
            if (StringUtil.equals("SUCCESS", elementValueToMap.get("result_code").toString())) {
                HashMap<String, Object> resultMap = new HashMap<>();
                resultMap.put("appId", elementValueToMap.get("appid"));
                resultMap.put("timeStamp", String.valueOf(System.currentTimeMillis()));
                resultMap.put("nonceStr", wxUtils.getRandomString(32));
                resultMap.put("package", "prepay_id=" + elementValueToMap.get("prepay_id"));
                resultMap.put("signType", "MD5");
                resultMap.put("paySign", WxConfig.getSign(resultMap));
                return ResultUtil.data(resultMap);
            }
            return ResultUtil.error("调起支付异常:" + elementValueToMap.get("return _msg"));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error("调起支付异常:" + e.getMessage());
        }
    }


    @GetMapping("/queryOrder")
    public Result<Object> queryOrder(@RequestParam("id") String id) throws IOException, ParseException {
        System.out.println("查询订单：" + id);
        WxUtils wxUtils = new WxUtils();
        Map<String, Object> map = new HashMap<String, Object>();
        // 公众账号ID
        map.put("appid", WeixinPayConfig.appid);
        // 商户号
        map.put("mch_id", WeixinPayConfig.mch_id);
        //订单号
        map.put("out_trade_no", id);
        // 随机字符串
        map.put("nonce_str", wxUtils.getRandomString(32));
        // 签名
        map.put("sign", WxConfig.getSign(map));
        String xml = XmlUtil.genXml(map);
        HttpResponse httpResponse = HttpClientUtil.sendXMLDataByPost(WeixinPayConfig.query_order_url, xml);
        HttpEntity entity = httpResponse.getEntity();
        InputStream content = entity.getContent();

        Map<String, Object> elementValueToMap = wxUtils.getElementValueToMap(content);
        String result_code = elementValueToMap.get("result_code").toString();
        log.info("查询订单结果： {}", elementValueToMap);
        if (StringUtil.isNotEmpty(result_code) && "SUCCESS".equals(result_code.toUpperCase())) {
            String trade_state = elementValueToMap.get("trade_state").toString();
            if ("SUCCESS".equals(trade_state.toUpperCase())) {
                String time_end = elementValueToMap.get("time_end").toString();
                String transaction_id = elementValueToMap.get("transaction_id").toString();
                Date yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss").parse(time_end);
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String format = simpleDateFormat.format(yyyyMMddHHmmss);
                Date parse = simpleDateFormat.parse(format);

                HmOrder byId = iHmOrderService.getById(id);
                if(byId.getStatus().intValue() >= 1) {
                    return new ResultUtil<>().setData("支付成功");
                }

                HmOrder hmOrder = new HmOrder();
                hmOrder.setPayTime(parse);
                hmOrder.setPayNumber(transaction_id);
                hmOrder.setId(id);
                hmOrder.setStatus(OrderEnum.ORDER_PAY.getIndex());
                iHmOrderService.updateById(hmOrder);
                return new ResultUtil<>().setData("支付成功");
            } else {
                HmOrder hmOrder = new HmOrder();
                hmOrder.setId(id);
                hmOrder.setStatus(OrderEnum.ORDER_ERROR.getIndex());
                iHmOrderService.updateById(hmOrder);
                return new ResultUtil<>().setErrorMsg("支付失败");
            }
        } else {
            String err_code_des = elementValueToMap.get("err_code_des").toString();
            HmOrder hmOrder = new HmOrder();
            hmOrder.setId(id);
            hmOrder.setStatus(OrderEnum.ORDER_ERROR.getIndex());
            iHmOrderService.updateById(hmOrder);
            return new ResultUtil<>().setErrorMsg(err_code_des);
        }
    }


    @RequestMapping(value = "payResult", method = {RequestMethod.GET, RequestMethod.POST})
    public Object payResult(@RequestBody String xmlData) throws JDOMException, IOException, ParseException {
        Map<String, String> map = XmlUtil.doXMLParse(xmlData);
        log.info("接收到支付回调： {}", map);
        String return_code = map.get("return_code").toUpperCase();
        String result_code = map.get("result_code").toUpperCase();
        HashMap<String, Object> resultMap = new HashMap<>();
        if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {
            //订单号
            String out_trade_no = map.get("out_trade_no");
            HmOrder hmOrder = iHmOrderService.getById(out_trade_no);
            //微信支付订单号
            String transaction_id = map.get("transaction_id");
            //支付完成时间
            String time_end = map.get("time_end");
            Date yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss").parse(time_end);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = simpleDateFormat.format(yyyyMMddHHmmss);
            Date parse = simpleDateFormat.parse(format);
            hmOrder.setPayTime(parse);
            hmOrder.setStatus(OrderEnum.ORDER_PAY.getIndex());
            hmOrder.setId(out_trade_no);
            hmOrder.setPayNumber(transaction_id);
            if (hmOrder.getIsSendMsg() == null || hmOrder.getIsSendMsg().intValue() != 1) {
                //需要给指定的技师推送订单通知
                Boolean aBoolean = wxConfig.sendWxgMessage(hmOrder.getId(), hmOrder.getOpenid(), hmOrder.getProjectName(), hmOrder.getOrderNum(),
                        DateUtil.format(hmOrder.getServiceTime(), "yyyy-MM-dd HH:mm"));
                if (aBoolean) {
                    hmOrder.setIsSendMsg(1);
                }
            }
            iHmOrderService.updateById(hmOrder);
            resultMap.put("return_code", "SUCCESS");
        }else {
            resultMap.put("return_code", "FAIL");
        }
        String xml = XmlUtil.genXml(resultMap);
        return xml;
    }

    @RequestMapping(value = "upProjectPayResult", method = {RequestMethod.GET, RequestMethod.POST})
    public Object upProjectPayResult(@RequestBody String xmlData) throws JDOMException, IOException, ParseException {
        Map<String, String> map = XmlUtil.doXMLParse(xmlData);
        log.info("接收到升级项目支付回调： {}", map);
        String return_code = map.get("return_code").toUpperCase();
        String result_code = map.get("result_code").toUpperCase();
        HashMap<String, Object> resultMap = new HashMap<>();
        if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {
            //订单号
            String out_trade_no = map.get("out_trade_no");
            QueryWrapper<HmOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(HmOrder::getOrderNum, out_trade_no);
            HmOrder hmOrder = iHmOrderService.getOne(queryWrapper);

            HmOrder updateOrder = new HmOrder();
            //微信支付订单号
            String transaction_id = map.get("transaction_id");
            //支付完成时间
            String time_end = map.get("time_end");
            Date yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss").parse(time_end);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = simpleDateFormat.format(yyyyMMddHHmmss);
            Date parse = simpleDateFormat.parse(format);
            updateOrder.setPayTime(parse);
            updateOrder.setStatus(OrderEnum.ORDER_PAY.getIndex());
            updateOrder.setId(hmOrder.getId());
            updateOrder.setPayNumber(transaction_id);
            updateOrder.setIsUp(1);
            HmProject hmProject = iHmProjectService.getById(map.get("attach"));
            if (hmProject != null) {
                updateOrder.setProjectId(hmProject.getId());
                updateOrder.setProjectName(hmProject.getTitle());
                updateOrder.setTimeLong(hmProject.getTimeLong());
                updateOrder.setOrderPrice(hmProject.getPrice());
            }
            iHmOrderService.updateById(updateOrder);
            resultMap.put("return_code", "SUCCESS");
        }else {
            resultMap.put("return_code", "FAIL");
        }
        String xml = XmlUtil.genXml(resultMap);
        return xml;
    }


    @GetMapping("/queryUpdateOrder")
    public Result<Object> queryUpdateOrder(@RequestParam("orderId") String orderId) throws IOException {
        System.out.println("根据订单号查询订单：" + orderId);
        HmOrder hmOrder = iHmOrderService.getById(orderId);

        WxUtils wxUtils = new WxUtils();
        Map<String, Object> map = new HashMap<String, Object>();
        // 公众账号ID
        map.put("appid", WeixinPayConfig.appid);
        // 商户号
        map.put("mch_id", WeixinPayConfig.mch_id);
        //订单号
        map.put("out_trade_no", hmOrder.getOrderNum());
        // 随机字符串
        map.put("nonce_str", wxUtils.getRandomString(32));
        // 签名
        map.put("sign", WxConfig.getSign(map));
        String xml = XmlUtil.genXml(map);
        HttpResponse httpResponse = HttpClientUtil.sendXMLDataByPost(WeixinPayConfig.query_order_url, xml);
        HttpEntity entity = httpResponse.getEntity();
        InputStream content = entity.getContent();

        Map<String, Object> elementValueToMap = wxUtils.getElementValueToMap(content);
        String result_code = elementValueToMap.get("result_code").toString();
        log.info("查询订单结果： {}", elementValueToMap);
        if (StringUtil.isNotEmpty(result_code) && "SUCCESS".equals(result_code.toUpperCase())) {
            String trade_state = elementValueToMap.get("trade_state").toString();
            if ("SUCCESS".equals(trade_state.toUpperCase())) {
                HmProject hmProject = iHmProjectService.getById(elementValueToMap.get("attach").toString());
                if (hmProject != null && hmOrder.getIsUp() == 0) {
                    HmOrder updateOrder = new HmOrder();
                    updateOrder.setProjectId(hmProject.getId());
                    updateOrder.setProjectName(hmProject.getTitle());
                    updateOrder.setTimeLong(hmProject.getTimeLong());
                    updateOrder.setOrderPrice(hmProject.getPrice());
                    updateOrder.setIsUp(1);
                    updateOrder.setId(hmOrder.getId());
                    iHmOrderService.updateById(updateOrder);
                }
                return new ResultUtil<>().setData("支付成功");
            }
            return new ResultUtil<>().setErrorMsg("支付失败");
        } else {
            String err_code_des = elementValueToMap.get("err_code_des").toString();
            return new ResultUtil<>().setErrorMsg(err_code_des);
        }
    }
}
